# -*- coding:utf-8 -*-
"""
@Author : 审心
@Time : 2023/9/8 17:48
任务线程类 V2 版本
"""
import json
import sys
import threading
import time
import traceback

import pythoncom

from autoTask.core.taskMapping import task_mapping
from common.logger.log import log_, create_file_log, flush_file_log
from common.utils.Base64Util import file_to_base64
from request.open.robot import append_task_statement_result_v2, update_status_v2
from config import data as config
from config.core.keys import ROBOT_NUMBER
import common.glv as glv

# 全局只能同时启动一个任务执行线程
start_task_thread_lock = threading.Lock()


class TaskThreadV2(threading.Thread):
    def __init__(self, req_param: dict):
        """
        初始化任务线程 v2
        :param req_param: 接收到任务时的请求参数
        """
        threading.Thread.__init__(self)
        self.req_param = req_param
        # 任务列表
        self.task_list = self.req_param.get('taskList')
        # 当前执行任务
        self.now_task = None
        # 任务状态 默认为 2成功 3失败
        self.now_task_status = 2
        # 当前任务日志处理器
        self.log_handler = None
        self._stop_event = threading.Event()
        self.log_task_info()

    def run(self):
        try:
            time.sleep(5)
            pythoncom.CoInitialize()
            for item in self.task_list:
                self.now_task = item
                self.now_task['param'] = json.loads(item.get('param'))
                self.execute_task()
        except:
            log_.error(f"启动线程时异常 : {sys.exc_info()}")
        finally:
            glv.set_item("task_thread", None)
            update_status_v2(config.get("robot.number"), 1)
            pythoncom.CoUninitialize()

    def stop(self):
        self._stop_event.set()

    def execute_task(self):
        if self.now_task is None:
            return
        try:
            self.before_handler()
            # 执行任务 存储结果至任务对象
            other = {
                "adId": self.req_param.get("adId"),
                "adEmail": self.req_param.get('adEmail'),
                "isTest": self.req_param.get('isTest')
            }
            self.now_task["result"] = task_mapping[str(self.now_task["robotTaskId"])](self.now_task, other)
        except:
            self.exception_handler()
        finally:
            self.after_handler()

    def before_handler(self):
        """
        执行任务之前处理
        :return:
        """
        self.log_handler = create_file_log(self.now_task.get("robotTaskName"), log_)
        # 更新机器状态为运行中
        update_status_v2(config.get(ROBOT_NUMBER), 2, self.now_task.get("statementId"),
                         self.now_task.get("robotTaskId"), self.now_task.get("robotTaskName"))

    def exception_handler(self):
        """
        发生异常时处理
        :return:
        """
        # 设置为任务执行失败状态
        self.now_task_status = 3
        self.now_task['err_msg'] = sys.exc_info()[1]
        log_.error(f"任务执行时异常 : {sys.exc_info()[1]}")
        log_.error(traceback.format_exc())

    def after_handler(self):
        """
        执行任务完成后处理
        :return:
        """
        try:
            log_base64 = None
            task_file_base64 = None
            task_file_suffix = None
            err_msg = self.now_task.get('err_msg') if self.now_task.get('err_msg') is not None else None
            if self.log_handler:
                # 输出日志至文件
                flush_file_log(log_, self.log_handler)
                # 将log文件转为 base64
                log_base64 = file_to_base64(self.log_handler.baseFilename, is_remove=True)
            if self.now_task.get('result'):
                task_file_base64 = self.now_task.get('result').get('task_file_base64')
                task_file_suffix = self.now_task.get('result').get('task_file_suffix')
            append_task_statement_result_v2(self.now_task.get("statementId"), self.now_task_status,
                                            task_file_base64=task_file_base64, task_file_suffix=task_file_suffix,
                                            task_log_base64=log_base64, errMsg=err_msg)
        except:
            log_.error(f"任务追加报表时异常 : {sys.exc_info()[0]} {sys.exc_info()[1]}")
            log_.error(traceback.format_exc())
        finally:
            time.sleep(5)
            # 更新机器至闲置状态
            update_status_v2(config.get("robot.number"), 1)

    def log_task_info(self):
        log_.info(
            f"管理员编号 : {self.req_param.get('adId')} | 管理员邮箱: {self.req_param.get('adEmail')} | 测试模式 : {self.req_param.get('isTest')} | 发布任务类型(1:普通/2:定时) : {self.req_param.get('pushTaskType')}")
        log_.info("==========发布单元列表==========")
        for item in self.req_param.get('taskList'):
            log_.info(
                f"编号 : {item.get('pushTaskId')} | 名称 : {item.get('name')} | 任务编号 : {item.get('robotTaskId')} | 任务名称: {item.get('robotTaskName')} | 报表编号 : {item.get('statementId')}")
            log_.info(f"参数 : {item.get('param')}")
        log_.info("===========================")


if __name__ == '__main__':
    update_status_v2(config.get("robot.number"), 1)
